home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 27 / CU Amiga Magazine's Super CD-ROM 27 (1998)(EMAP Images)(GB)[!][issue 1998-10].iso / CUCD / Programming / FreshBar / Source / ARexxPort.cpp next >
Encoding:
C/C++ Source or Header  |  1998-05-25  |  7.3 KB  |  327 lines

  1. //****************************************************************//
  2. // Filename:    ARexxPort.cpp
  3. // Autor:       Christian Taulien of Strange Intelligence
  4. // Purpose:     Testprogram for the SIFC
  5. // Creation:    11. Mai 1998
  6. //****************************************************************//
  7.  
  8. #include <stdio.h>
  9. #include <ctype.h>
  10.  
  11. #include "SIFC_Strings.h"
  12. #include "global.h"
  13. #include "ARexxPort.h"
  14.  
  15. #include <exec/types.h>
  16. #include <dos/dos.h>
  17. #include <rexx/storage.h>
  18.  
  19. #include <clib/exec_protos.h>
  20. #include <clib/rexxsyslib_protos.h>
  21. #include <clib/dos_protos.h>
  22. #include <clib/alib_protos.h>
  23.  
  24. ARexxPortC::ARexxPortC(char *arg_sPortName, struct ARexxCommand **arg_ppoCommands)
  25. /*S*/
  26. {
  27.   TRACE("Entry");
  28.   setCommandList(arg_ppoCommands);
  29.   m_bPortInstalled = FALSE;
  30.   m_bProcessing = FALSE;
  31.   setupARexxHost(arg_sPortName);
  32. }
  33. /*E*/
  34. ARexxPortC::~ARexxPortC()
  35. /*S*/
  36. {
  37.   TRACE("Entry");
  38.   closeDownARexxHost();
  39. }
  40. /*E*/
  41.  
  42. BOOL ARexxPortC::setupARexxHost(char *arg_sPortName)
  43. /*S*/
  44. {
  45.   TRACE("Entry");
  46.   // einen bereits geöffneten Port schließen.
  47.   if (isOpen())
  48.   {
  49.     closeDownARexxHost();
  50.   } // if
  51.  
  52.   // Nur mit gültigen Portnamen weitermachen.
  53.   if (!arg_sPortName)
  54.   {
  55.     return FALSE;
  56.   } // if
  57.  
  58.   // den Message Port erstellen
  59.   m_poPort = CreateMsgPort();
  60.   if (!m_poPort)
  61.   {
  62.     return FALSE;
  63.   }
  64.  
  65.   m_poPort->mp_Node.ln_Pri = 0;
  66.  
  67.   // MultiTasking ausschalten
  68.   Forbid();
  69.  
  70.   // Wenn dieser Port schon vorhanden ist, dann neue Extension anhängen
  71.   int ext = 0;
  72.   do
  73.   {
  74.     char temp[20];
  75.     sprintf(temp, ".%d", ++ext);
  76.     m_oPortName = arg_sPortName;
  77.     m_oPortName+= (char *) temp;
  78.   } while (FindPort(m_oPortName));
  79.  
  80.   // Jetzt den Portnamen eintragen
  81.   m_poPort->mp_Node.ln_Name = m_oPortName;
  82.   AddPort(m_poPort);
  83.  
  84.   // MultiTasking wieder anschalten
  85.   Permit();
  86.  
  87.   // ReadArgs-Struktur erzeugen
  88.   if (!(m_poRDArgs = (struct RDArgs *) AllocDosObject(DOS_RDARGS, NULL)))
  89.   {
  90.     RemPort(m_poPort);
  91.     DeleteMsgPort(m_poPort);
  92.     return FALSE;
  93.   } // if
  94.  
  95.   m_poRDArgs->RDA_Flags = RDAF_NOPROMPT;
  96.   m_bPortInstalled = TRUE;
  97. return TRUE;
  98. }
  99. /*E*/
  100. void ARexxPortC::closeDownARexxHost(void)
  101. /*S*/
  102. {
  103.   TRACE("Entry");
  104.   // Test, ob überhaub ein Port vorhanden ist.
  105.   if (m_poPort)
  106.   {
  107.     // Port abmelden
  108.     RemPort(m_poPort);
  109.  
  110.     // MsgPort leeren
  111.     struct RexxMsg *rexxmsg;
  112.     while (rexxmsg = (struct RexxMsg *) GetMsg(m_poPort))
  113.     {
  114.       replyRexxCommand(rexxmsg, -20, (LONG) "Host closing down", NULL);
  115.     } // while
  116.  
  117.     DeleteMsgPort(m_poPort);
  118.     m_poPort = NULL;
  119.   } // if
  120.  
  121.   // Freigeben der ReadArgs-Struktur
  122.   if (m_poRDArgs )
  123.   {
  124.     FreeDosObject(DOS_RDARGS, m_poRDArgs);
  125.     m_poRDArgs = NULL;
  126.   } // if
  127.   m_bPortInstalled = FALSE;
  128. }
  129. /*E*/
  130. void ARexxPortC::replyRexxCommand(struct RexxMsg *arg_poRexxMsg, LONG arg_lPrimary, LONG arg_lSecondary, char *arg_sResult)
  131. /*S*/
  132. {
  133.   TRACE("Entry");
  134.   // Wenn Ergebnis gefordert...
  135.   if (arg_poRexxMsg->rm_Action & RXFF_RESULT )
  136.   {
  137.     // Wenn primary=0, dann soll das Ergebnis in result2 abgelegt werden
  138.     if (arg_lPrimary == 0)
  139.     {
  140.       // Wenn es ein Ergebnis gibt, dann in secondary den ArgString eintragen
  141.       if (arg_sResult)
  142.       {
  143.         arg_lSecondary = (long) CreateArgstring(arg_sResult, strlen(arg_sResult));
  144.       }
  145.       else
  146.       {
  147.         arg_lSecondary = NULL;
  148.       } // if
  149.     }
  150.     else
  151.     {
  152.       char buf[20];
  153.       // Wenn primary>0 dann liegt eine fehlernummer vor
  154.       if( arg_lPrimary > 0 )
  155.       {
  156.         sprintf(buf, "%ld", arg_lSecondary);
  157.         arg_sResult = buf;
  158.       }
  159.       else
  160.       {
  161.         // Wenn primary<0 dann liegt in arg_lSecondary ein Fehlertext vor
  162.         arg_lPrimary = -arg_lPrimary;
  163.         arg_sResult = (char *) arg_lSecondary;
  164.       } // if
  165.  
  166.       // RC2 mit dem Fehlertext füllen
  167.       SetRexxVar((struct Message *) arg_poRexxMsg, "RC2", arg_sResult, strlen(arg_sResult) );
  168.  
  169.       // secondary wieder löschen
  170.       arg_lSecondary = 0;
  171.     } // if
  172.   }
  173.   else if (arg_lPrimary < 0)
  174.   {
  175.     // Bei negativer primary in positive primary wandeln
  176.     arg_lPrimary = -arg_lPrimary;
  177.   } // if
  178.  
  179.   // Result-Felder ausfüllen
  180.   arg_poRexxMsg->rm_Result1 = arg_lPrimary;
  181.   arg_poRexxMsg->rm_Result2 = arg_lSecondary;
  182.  
  183.   // Zurückschicken der Nachricht
  184.   ReplyMsg((struct Message *) arg_poRexxMsg);
  185. }
  186. /*E*/
  187. BOOL ARexxPortC::processARexxCommand(void)
  188. /*S*/
  189. {
  190. BOOL error=FALSE;
  191.   TRACE("Entry");
  192.   m_bProcessing = TRUE;
  193.  
  194.   // solange eine Message am Port anliegt
  195.   struct RexxMsg *oARexxMsg;
  196.   while (!error && (oARexxMsg = (struct RexxMsg *) GetMsg(m_poPort)))
  197.   {
  198.     // wenn ein ARexx-Befehl vorliegt
  199.     if (((oARexxMsg->rm_Action & RXCODEMASK) == RXCOMM) && ARG0(oARexxMsg))
  200.     {
  201.       error=doRXCommand(oARexxMsg);
  202.     }
  203.     else // Sonst einfach ReplyMsg
  204.     {
  205.       ReplyMsg((struct Message *) oARexxMsg);
  206.     } // if
  207.   } // while
  208.  
  209.   m_bProcessing = FALSE;
  210.  
  211. return error;
  212. }
  213. /*E*/
  214. struct ARexxCommand *ARexxPortC::findARexxCommand(StringC &arg_roCmdName)
  215. /*S*/
  216. {
  217.   TRACE("Entry");
  218.   if (!m_ppoCommands)
  219.   {
  220.     return NULL;
  221.   } // if
  222.  
  223.   // suche den ARexx-Befehl in der Liste
  224.   struct ARexxCommand *poFound = NULL;
  225.   for (int i=0;m_ppoCommands[i] && !poFound;i++)
  226.   {
  227.     if (arg_roCmdName == m_ppoCommands[i]->m_sName)
  228.     {
  229.       poFound = m_ppoCommands[i];
  230.     } // if
  231.   } // for
  232. return poFound;
  233. }
  234. /*E*/
  235. BOOL ARexxPortC::doRXCommand(struct RexxMsg *arg_poARexxMsg)
  236. /*S*/
  237. {
  238.   TRACE("Entry");
  239.   // Das 1. Argument im RexxMsg-Struktur Member Args[] ist der Befehl selbst
  240.   char *sBef = arg_poARexxMsg->rm_Args[0];
  241.  
  242.   for (int i=0, c=sBef[0]; isalnum(c) || c=='_'; c=sBef[++i]);
  243.   StringC oARexxCmd(sBef, i);
  244.   StringC oArgs(((char*) sBef+i));
  245.   oArgs.trimString();
  246.   oArgs += '\n';
  247.  
  248.   struct ARexxCommand *poFound = findARexxCommand(oARexxCmd);
  249.  
  250.   // wenn ARexx-Befehl nicht gefunden
  251.   if (!poFound)
  252.   {
  253.     replyRexxCommand(arg_poARexxMsg, 20, ERROR_NOT_IMPLEMENTED, NULL);
  254.     return FALSE;
  255.   } // if
  256.  
  257.   BOOL done=FALSE;
  258.   long rc=20;
  259.   long rc2=0;
  260.   LONG alArgArray[16];
  261.  
  262.   // Wenn dieser Befehl Argumente annimmt
  263.   if (poFound->m_sArgs)
  264.   {
  265.     m_poRDArgs->RDA_Source.CS_Buffer = oArgs;
  266.     m_poRDArgs->RDA_Source.CS_Length = oArgs.getLength();
  267.     m_poRDArgs->RDA_Source.CS_CurChr = 0;
  268.     m_poRDArgs->RDA_DAList = NULL;
  269.     m_poRDArgs->RDA_Buffer = NULL;
  270.  
  271.     // Argumenten-Array nullen
  272.     memset(alArgArray, 0, sizeof(LONG)*16);
  273.  
  274.     // Argumente einlesen
  275.     if (!ReadArgs(poFound->m_sArgs, &alArgArray[0], m_poRDArgs))
  276.     {
  277.       rc = 10;
  278.       rc2 = IoErr();
  279.     } // if
  280.   } // if
  281.  
  282.   // Wenn noch alles ok
  283.   StringC oResult;
  284.   if (!rc2)
  285.   {
  286.     done = dispatchARexxCommand(poFound->m_ulCommandID, &alArgArray[0], rc, rc2, oResult);
  287.     if (!oResult.isEmpty() && (rc==0) && (arg_poARexxMsg->rm_Action & RXFF_RESULT))
  288.     {
  289.       if (SetRexxVar((struct Message *) arg_poARexxMsg, "RESULT", oResult, oResult.getLength()))
  290.       {
  291.         rc = -10;
  292.         rc2 = (long) "Unable to set ARexx variable";
  293.       } // if
  294.     } // if
  295.   } // if
  296.  
  297.   replyRexxCommand(arg_poARexxMsg, rc, rc2, (char *) oResult);
  298.  
  299.   // benutzten Speicher freigeben
  300.   FreeArgs(m_poRDArgs );
  301.  
  302. return done;
  303. }
  304. /*E*/
  305. BOOL ARexxPortC::dispatchARexxCommand(ULONG arg_ulCmdID, LONG *arg_alArgArray, LONG &arg_rlRC, LONG &arg_rlRC2, StringC &roResult)
  306. /*S*/
  307. {
  308. BOOL done = FALSE;
  309.   TRACE("Entry");
  310.   roResult.emptyString();
  311.   arg_rlRC = NULL;
  312.   arg_rlRC2 = NULL;
  313.  
  314.   switch (arg_ulCmdID)
  315.   {
  316.     default:
  317.       TRACE("nicht implementierter ARexx-Befehl");
  318.       arg_rlRC = 20;
  319.       arg_rlRC2 = ERROR_NOT_IMPLEMENTED;
  320.       break;
  321.   } // switch
  322. return done;
  323. }
  324. /*E*/
  325.  
  326.  
  327.